home *** CD-ROM | disk | FTP | other *** search
/ Chip 2007 January, February, March & April / Chip-Cover-CD-2007-02.iso / Pakiet internetowy / Rozne / HTTrack 3.40-2 / httrack-3.40-2.exe / {app} / src / minizip / mztools.c < prev    next >
C/C++ Source or Header  |  2005-09-24  |  8KB  |  288 lines

  1. /*
  2.   Additional tools for Minizip
  3.   Code: Xavier Roche '2004
  4.   License: Same as ZLIB (www.gzip.org)
  5. */
  6.  
  7. /* Code */
  8. #include <string.h>
  9. #ifndef _WIN32_WCE
  10. #include <stdio.h>
  11. #include <stdlib.h>
  12. #else
  13. #include <stdio.h>
  14. #include <stdlib.h>
  15. #include "celib.h"
  16. #endif
  17. #include "zlib.h"
  18. #include "unzip.h"
  19.  
  20. #define READ_8(adr)  ((unsigned char)*(adr))
  21. #define READ_16(adr) ( READ_8(adr) | (READ_8(adr+1) << 8) )
  22. #define READ_32(adr) ( READ_16(adr) | (READ_16((adr)+2) << 16) )
  23.  
  24. #define WRITE_8(buff, n) do { \
  25.   *((unsigned char*)(buff)) = (unsigned char) ((n) & 0xff); \
  26. } while(0)
  27. #define WRITE_16(buff, n) do { \
  28.   WRITE_8((unsigned char*)(buff), n); \
  29.   WRITE_8(((unsigned char*)(buff)) + 1, (n) >> 8); \
  30. } while(0)
  31. #define WRITE_32(buff, n) do { \
  32.   WRITE_16((unsigned char*)(buff), (n) & 0xffff); \
  33.   WRITE_16((unsigned char*)(buff) + 2, (n) >> 16); \
  34. } while(0)
  35.  
  36. extern int ZEXPORT unzRepair(file, fileOut, fileOutTmp, nRecovered, bytesRecovered)
  37. const char* file;
  38. const char* fileOut;
  39. const char* fileOutTmp;
  40. uLong* nRecovered;
  41. uLong* bytesRecovered;
  42. {
  43.   int err = Z_OK;
  44.   FILE* fpZip = fopen(file, "rb");
  45.   FILE* fpOut = fopen(fileOut, "wb");
  46.   FILE* fpOutCD = fopen(fileOutTmp, "wb");
  47.   if (fpZip != NULL &&  fpOut != NULL) {
  48.     int entries = 0;
  49.     uLong totalBytes = 0;
  50.     char header[30];
  51.     char filename[256];
  52.     char extra[1024];
  53.     int offset = 0;
  54.     int offsetCD = 0;
  55.     while ( fread(header, 1, 30, fpZip) == 30 ) {
  56.       int currentOffset = offset;
  57.  
  58.       /* File entry */
  59.       if (READ_32(header) == 0x04034b50) {
  60.         unsigned int version = READ_16(header + 4);
  61.         unsigned int gpflag = READ_16(header + 6);
  62.         unsigned int method = READ_16(header + 8);
  63.         unsigned int filetime = READ_16(header + 10);
  64.         unsigned int filedate = READ_16(header + 12);
  65.         unsigned int crc = READ_32(header + 14); /* crc */
  66.         unsigned int cpsize = READ_32(header + 18); /* compressed size */
  67.         unsigned int uncpsize = READ_32(header + 22); /* uncompressed sz */
  68.         unsigned int fnsize = READ_16(header + 26); /* file name length */
  69.         unsigned int extsize = READ_16(header + 28); /* extra field length */
  70.         filename[0] = extra[0] = '\0';
  71.         
  72.         /* Header */
  73.         if (fwrite(header, 1, 30, fpOut) == 30) {
  74.           offset += 30;
  75.         } else {
  76.           err = Z_ERRNO;
  77.           break;
  78.         }
  79.         
  80.         /* Filename */
  81.         if (fnsize > 0) {
  82.           if (fread(filename, 1, fnsize, fpZip) == fnsize) {
  83.             if (fwrite(filename, 1, fnsize, fpOut) == fnsize) {
  84.               offset += fnsize;
  85.             } else {
  86.               err = Z_ERRNO;
  87.               break;
  88.             }
  89.           } else {
  90.             err = Z_ERRNO;
  91.             break;
  92.           }
  93.         } else {
  94.           err = Z_STREAM_ERROR;
  95.           break;
  96.         }
  97.  
  98.         /* Extra field */
  99.         if (extsize > 0) {
  100.           if (fread(extra, 1, extsize, fpZip) == extsize) {
  101.             if (fwrite(extra, 1, extsize, fpOut) == extsize) {
  102.               offset += extsize;
  103.             } else {
  104.               err = Z_ERRNO;
  105.               break;
  106.             }
  107.           } else {
  108.             err = Z_ERRNO;
  109.             break;
  110.           }
  111.         }
  112.         
  113.         /* Data */
  114.         {
  115.           int dataSize = cpsize;
  116.           if (dataSize == 0) {
  117.             dataSize = uncpsize;
  118.           }
  119.           if (dataSize > 0) {
  120.             char* data = malloc(dataSize);
  121.             if (data != NULL) {
  122.               if ((int)fread(data, 1, dataSize, fpZip) == dataSize) {
  123.                 if ((int)fwrite(data, 1, dataSize, fpOut) == dataSize) {
  124.                   offset += dataSize;
  125.                   totalBytes += dataSize;
  126.                 } else {
  127.                   err = Z_ERRNO;
  128.                 }
  129.               } else {
  130.                 err = Z_ERRNO;
  131.               }
  132.               free(data);
  133.               if (err != Z_OK) {
  134.                 break;
  135.               }
  136.             } else {
  137.               err = Z_MEM_ERROR;
  138.               break;
  139.             }
  140.           }
  141.         }
  142.         
  143.         /* Central directory entry */
  144.         {
  145.           char header[46];
  146.           char* comment = "";
  147.           int comsize = (int) strlen(comment);
  148.           WRITE_32(header, 0x02014b50);
  149.           WRITE_16(header + 4, version);
  150.           WRITE_16(header + 6, version);
  151.           WRITE_16(header + 8, gpflag);
  152.           WRITE_16(header + 10, method);
  153.           WRITE_16(header + 12, filetime);
  154.           WRITE_16(header + 14, filedate);
  155.           WRITE_32(header + 16, crc);
  156.           WRITE_32(header + 20, cpsize);
  157.           WRITE_32(header + 24, uncpsize);
  158.           WRITE_16(header + 28, fnsize);
  159.           WRITE_16(header + 30, extsize);
  160.           WRITE_16(header + 32, comsize);
  161.           WRITE_16(header + 34, 0);     /* disk # */
  162.           WRITE_16(header + 36, 0);     /* int attrb */
  163.           WRITE_32(header + 38, 0);     /* ext attrb */
  164.           WRITE_32(header + 42, currentOffset);
  165.           /* Header */
  166.           if (fwrite(header, 1, 46, fpOutCD) == 46) {
  167.             offsetCD += 46;
  168.             
  169.             /* Filename */
  170.             if (fnsize > 0) {
  171.               if (fwrite(filename, 1, fnsize, fpOutCD) == fnsize) {
  172.                 offsetCD += fnsize;
  173.               } else {
  174.                 err = Z_ERRNO;
  175.                 break;
  176.               }
  177.             } else {
  178.               err = Z_STREAM_ERROR;
  179.               break;
  180.             }
  181.             
  182.             /* Extra field */
  183.             if (extsize > 0) {
  184.               if (fwrite(extra, 1, extsize, fpOutCD) == extsize) {
  185.                 offsetCD += extsize;
  186.               } else {
  187.                 err = Z_ERRNO;
  188.                 break;
  189.               }
  190.             }
  191.             
  192.             /* Comment field */
  193.             if (comsize > 0) {
  194.               if ((int)fwrite(comment, 1, comsize, fpOutCD) == comsize) {
  195.                 offsetCD += comsize;
  196.               } else {
  197.                 err = Z_ERRNO;
  198.                 break;
  199.               }
  200.             }
  201.             
  202.             
  203.           } else {
  204.             err = Z_ERRNO;
  205.             break;
  206.           }
  207.         }
  208.  
  209.         /* Success */
  210.         entries++;
  211.  
  212.       } else {
  213.         break;
  214.       }
  215.     }
  216.  
  217.     /* Final central directory  */
  218.     {
  219.       int entriesZip = entries;
  220.       char header[22];
  221.       char* comment = ""; // "ZIP File recovered by zlib/minizip/mztools";
  222.       int comsize = (int) strlen(comment);
  223.       if (entriesZip > 0xffff) {
  224.         entriesZip = 0xffff;
  225.       }
  226.       WRITE_32(header, 0x06054b50);
  227.       WRITE_16(header + 4, 0);    /* disk # */
  228.       WRITE_16(header + 6, 0);    /* disk # */
  229.       WRITE_16(header + 8, entriesZip);   /* hack */
  230.       WRITE_16(header + 10, entriesZip);  /* hack */
  231.       WRITE_32(header + 12, offsetCD);    /* size of CD */
  232.       WRITE_32(header + 16, offset);      /* offset to CD */
  233.       WRITE_16(header + 20, comsize);     /* comment */
  234.       
  235.       /* Header */
  236.       if (fwrite(header, 1, 22, fpOutCD) == 22) {
  237.         
  238.         /* Comment field */
  239.         if (comsize > 0) {
  240.           if ((int)fwrite(comment, 1, comsize, fpOutCD) != comsize) {
  241.             err = Z_ERRNO;
  242.           }
  243.         }
  244.         
  245.       } else {
  246.         err = Z_ERRNO;
  247.       }
  248.     }
  249.  
  250.     /* Final merge (file + central directory) */
  251.     fclose(fpOutCD);
  252.     if (err == Z_OK) {
  253.       fpOutCD = fopen(fileOutTmp, "rb");
  254.       if (fpOutCD != NULL) {
  255.         int nRead;
  256.         char buffer[8192];
  257.         while ( (nRead = fread(buffer, 1, sizeof(buffer), fpOutCD)) > 0) {
  258.           if ((int)fwrite(buffer, 1, nRead, fpOut) != nRead) {
  259.             err = Z_ERRNO;
  260.             break;
  261.           }
  262.         }
  263.         fclose(fpOutCD);
  264.       }
  265.     }
  266.     
  267.     /* Close */
  268.     fclose(fpZip);
  269.     fclose(fpOut);
  270.     
  271.     /* Wipe temporary file */
  272.     (void)remove(fileOutTmp);
  273.     
  274.     /* Number of recovered entries */
  275.     if (err == Z_OK) {
  276.       if (nRecovered != NULL) {
  277.         *nRecovered = entries;
  278.       }
  279.       if (bytesRecovered != NULL) {
  280.         *bytesRecovered = totalBytes;
  281.       }
  282.     }
  283.   } else {
  284.     err = Z_STREAM_ERROR;
  285.   }
  286.   return err;
  287. }
  288.